<script setup lang="ts">
import { onBeforeUnmount, computed, PropType, unref, nextTick, ref, watch, shallowRef } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { IDomEditor, IEditorConfig, i18nChangeLanguage } from '@wangeditor/editor'
import { propTypes } from '@/utils/propTypes'
import { isNumber } from '@/utils/is'
import { ElMessage } from 'element-plus'
import { useLocaleStore } from '@/store/modules/locale'
import { useRouter } from 'vue-router'
import type { UploadProps, UploadUserFile } from 'element-plus'
import { useAppStoreWithOut } from '@/store/modules/app'
import { useStorage } from '@/hooks/web/useStorage'
import axios from "axios"
const { getStorage } = useStorage()
const appStore = useAppStoreWithOut()
const userInfo = getStorage(appStore.getUserInfo)
const localeStore = useLocaleStore()

const currentLocale = computed(() => localeStore.getCurrentLocale)

i18nChangeLanguage(unref(currentLocale).lang)

const props = defineProps({
  editorId: propTypes.string.def('wangeEditor-1'),
  height: propTypes.oneOfType([Number, String]).def('500px'),
  editorConfig: {
    type: Object as PropType<IEditorConfig>,
    default: () => undefined
  },
  modelValue: propTypes.string.def('')
})
// const toolbarConfig: Partial<IToolbarConfig> = {  // TS 语法
// // const toolbarConfig = {                        // JS 语法
//     /* 工具栏配置 */
// }
// console.log("默认工具栏:",Toolbar.getConfig());

const toolbarConfig: any = {} // TS 语法
// toolbarConfig.toolbarKeys = [
//   "bold",
// ]
toolbarConfig.excludeKeys = [
  // "color",
  // "bold",
  // "italic",
  // "underline",
  "blockquote",
  "code",
  "emotion",
  // "group-image",
  // "group-video",
  // "insertTable",
  "codeBlock",
  "divider",
  "fullScreen"
]

const emit = defineEmits(['change', 'update:modelValue'])

// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef<IDomEditor>()

const valueHtml = ref('')

watch(
  () => props.modelValue,
  (val: string) => {
    if (val === unref(valueHtml)) return
    valueHtml.value = val
  },
  {
    immediate: true
  }
)

// 监听
watch(
  () => valueHtml.value,
  (val: string) => {
    emit('update:modelValue', val)
  }
)

const handleCreated = (editor: IDomEditor) => {
  editorRef.value = editor
}
type InsertFnType = (url: string, alt: string, href: string) => void
type InsertFnTypes = (url: string, poster: string) => void
// 编辑器配置
const editorConfig = computed((): IEditorConfig => {
  return Object.assign(
    {
      placeholder: "请输入内容",
      readOnly: false,
      customAlert: (s: string, t: string) => {
        switch (t) {
          case 'success':
            ElMessage.success(s)
            break
          case 'info':
            ElMessage.info(s)
            break
          case 'warning':
            ElMessage.warning(s)
            break
          case 'error':
            ElMessage.error(s)
            break
          default:
            ElMessage.info(s)
            break
        }
      },
      autoFocus: false,
      scroll: true,
      uploadImgShowBase64: true,
      MENU_CONF: {
        uploadImage: {
          fieldName: 'file',
          allowedFileTypes: ['image/*'],
          maxNumberOfFiles: 10,
          maxFileSize: 1 * 1024 * 1024, // 1M
          server: '/api/resource/oss/upload',
          withCredentials: true,
          // headers: {
          //   "Authorization": `Bearer ${userInfo ? userInfo.access_token : ""}`,
          //   "clientid": userInfo ? userInfo.client_id : "e5cd7e4891bf95d1d19206ce24a7b32e"
          // },
          async customUpload(file: File, insertFn: InsertFnType) {  // TS 语法
            // async customUpload(file, insertFn) {                   // JS 语法
            // file 即选中的文件
            // 自己实现上传，并得到图片 url alt href
            // 最后插入图片
            const formData = new FormData()
            formData.append('file', file)
            axios.post('/api/resource/oss/upload', formData, {
              headers: {
                'Content-Type': 'multipart/form-data',
                "Authorization": `Bearer ${userInfo ? userInfo.access_token : ""}`,
                "clientid": userInfo ? userInfo.client_id : "e5cd7e4891bf95d1d19206ce24a7b32e"
              }
            }).then(response => {
              console.log(response.data.data);
              let res=response.data
              // 如果上传成功，调用 insertImgFn 插入图片到编辑器  
              insertFn(res.data.url, res.data.fileName, res.data.url)
            }).catch(error => {
              // 处理上传失败的情况  
              console.error('上传图片失败:', error)
            })
          }
          // 单个文件上传成功之后
          // onSuccess(file: File, res: any) {  // TS 语法
          //   console.log(file, res);
          //   // onSuccess(file, res) {          // JS 语法
          //   console.log(`${file.name} 上传成功`, res)
          //   ElMessage.success(`${file.name} 上传成功`)
          // },
          // 单个文件上传失败
          // onFailed(file: File, res: any) {   // TS 语法
          //   // onFailed(file, res) {           // JS 语法
          //   console.log(`${file.name} 上传失败`, res)
          //   ElMessage.error(`${file.name} 上传失败`)

          // },
          // 上传错误，或者触发 timeout 超时
          // onError(file: File, err: any, res: any) {  // TS 语法
          //   // onError(file, err, res) {               // JS 语法
          //   console.log(`${file.name} 上传出错`, err, res)
          //   ElMessage.error(`${file.name} 上传出错`)

          // },
          // customInsert(res: any, insertFn: InsertFnType) {  // TS 语法
          //   // customInsert(res, insertFn) {                  // JS 语法
          //   // res 即服务端的返回结果
          //   console.log("服务端返回：", res);
          //   // 从 res 中找到 url alt href ，然后插入图片
          //   insertFn(res.data.url, res.data.fileName, res.data.url)
          // },
        },
        uploadVideo: {
          fieldName: 'file',
          allowedFileTypes: ['video/*'],
          maxNumberOfFiles: 5,
          maxFileSize: 10 * 1024 * 1024, // 10M
          server: '/api/resource/oss/upload',
          withCredentials: true,
          // headers: {
          //   "Authorization": `Bearer ${userInfo ? userInfo.access_token : ""}`,
          //   "clientid": userInfo ? userInfo.client_id : "e5cd7e4891bf95d1d19206ce24a7b32e"
          // },
          async customUpload(file: File, insertFns: InsertFnTypes) {  // TS 语法
            // async customUpload(file, insertFn) {                   // JS 语法
            // file 即选中的文件
            // 自己实现上传，并得到图片 url alt href
            // 最后插入图片
            const formData = new FormData()
            formData.append('file', file)
            axios.post('/api/resource/oss/upload', formData, {
              headers: {
                'Content-Type': 'multipart/form-data',
                "Authorization": `Bearer ${userInfo ? userInfo.access_token : ""}`,
                "clientid": userInfo ? userInfo.client_id : "e5cd7e4891bf95d1d19206ce24a7b32e"
              }
            }).then(response => {
              console.log(response.data.data);
              let res=response.data
              // 如果上传成功，调用 insertImgFn 插入图片到编辑器  
              insertFns(res.data.url, res.data.fileName)
            }).catch(error => {
              // 处理上传失败的情况  
              console.error('上传视频失败:', error)
            })
          }


          // 单个文件上传成功之后
          // onSuccess(file: File, res: any) {  // TS 语法
          //   console.log(file, res);
          //   // onSuccess(file, res) {          // JS 语法
          //   console.log(`${file.name} 上传成功`, res)
          //   ElMessage.success(`${file.name} 上传成功`)
          // },
          // 单个文件上传失败
          // onFailed(file: File, res: any) {   // TS 语法
          //   // onFailed(file, res) {           // JS 语法
          //   console.log(`${file.name} 上传失败`, res)
          //   ElMessage.error(`${file.name} 上传失败`)

          // },
          // 上传错误，或者触发 timeout 超时
          // onError(file: File, err: any, res: any) {  // TS 语法
          //   // onError(file, err, res) {               // JS 语法
          //   console.log(`${file.name} 上传出错`, err, res)
          //   ElMessage.error(`${file.name} 上传出错`)

          // },
          // customInsert(res: any, insertFns: InsertFnTypes) {  // TS 语法
          //   // customInsert(res, insertFn) {                  // JS 语法
          //   // res 即服务端的返回结果
          //   console.log("服务端返回：", res);

          //   // 从 res 中找到 url alt href ，然后插入图片
          //   insertFns(res.data.url, res.data.fileName)
          // },
        }
      }
    },
    props.editorConfig || {}
  )
})

const editorStyle = computed(() => {
  return {
    height: isNumber(props.height) ? `${props.height}px` : props.height
  }
})

// 回调函数
const handleChange = (editor: IDomEditor) => {
  emit('change', editor)
}

// 组件销毁时，及时销毁编辑器
onBeforeUnmount(() => {
  const editor = unref(editorRef.value)

  // 销毁，并移除 editor
  editor?.destroy()
})

const getEditorRef = async (): Promise<IDomEditor> => {
  await nextTick()
  return unref(editorRef.value) as IDomEditor
}

defineExpose({
  getEditorRef
})
</script>

<template>
  <div class="border-1 border-solid border-[var(--el-border-color)] z-10">
    <!-- 工具栏 -->
    <Toolbar :editor="editorRef" :editorId="editorId" :defaultConfig="toolbarConfig"
      class="border-0 b-b-1 border-solid border-[var(--el-border-color)]" />
    <!-- 编辑器 -->
    <Editor v-model="valueHtml" :editorId="editorId" :defaultConfig="editorConfig" :style="editorStyle"
      @on-change="handleChange" @on-created="handleCreated" />
  </div>
</template>

<style src="@wangeditor/editor/dist/css/style.css"></style>
